<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>

</head>

<body>
  <script>
    function testFun(a, b) {
      console.log(this);
      console.log(a + b);
    }



    //testFun.call(testObj,1, 2)

    Function.prototype.myCall = function (context, ...args) {
      //如果传来的this对象为 null 或 undefined
      if (context === null || context === undefined) {
        //this指向设置为window
        context = window
      } else {
        //值为原始值（数字、字符串、布尔值）的，this指向其原始值实例对象
        context = Object(context)
      }

      //定义一个Symbol类型的变量，用于存储函数
      const tempMethod = Symbol('临时存储在context对象上的方法')
      //将调用该call方法的函数，添加为目标this对象的自有函数
      context[tempMethod] = this
      //通过目标this对象的属性，调用该方法，实现this隐式绑定  并传入参数
      let result = context[tempMethod](...args)
      //删除目标this对象内的属性
      delete context[tempMethod]
      return result
    }

    var testObj = {
      name: '张三',
      age: 18
    }
    testFun.myCall(testObj, 1, 2, 3)
  </script>

</body>

</html>